package xyz.csmcool.imchat.service.impl;

import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import org.springframework.web.multipart.MultipartFile;
import xyz.csmcool.imchat.constants.Filetype;
import xyz.csmcool.imchat.entity.FileInfo;
import xyz.csmcool.imchat.entity.FileMessageVo;
import xyz.csmcool.imchat.entity.PrivateChats;
import xyz.csmcool.imchat.entity.RoomsChats;
import xyz.csmcool.imchat.entity.vo.RoomChatsVo;
import xyz.csmcool.imchat.feignclient.OssClint;
import xyz.csmcool.imchat.feignclient.RoomClient;
import xyz.csmcool.imchat.feignclient.UserClient;
import xyz.csmcool.imchat.mapper.PrivateChatsMapper;
import xyz.csmcool.imchat.service.IPrivateChatsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.csmcool.imchat.service.RabbitmqService;
import xyz.csmcool.imutil.ExceptionHandler.CommonException;
import xyz.csmcool.imutil.dto.LastPrivateMessageDto;
import xyz.csmcool.imutil.dto.PrivateMessage;
import xyz.csmcool.imutil.dto.UserDto;
import xyz.csmcool.imutil.utils.BeanUtil;
import xyz.csmcool.imutil.webVo.MyPage;
import xyz.csmcool.imutil.webVo.ResultCode;
import xyz.csmcool.imutil.webVo.ResultVo;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author csmcool
 * @since 2022-08-24
 */
@Service
@RequiredArgsConstructor
public class PrivateChatsServiceImpl extends ServiceImpl<PrivateChatsMapper, PrivateChats> implements IPrivateChatsService {

    final RabbitmqService rabbitmqService;
    final UserClient userClient;
    final RoomClient roomClient;
    final OssClint ossClint;
    final PrivateChatsMapper privateChatsMapper;

    /**
     * 发送私信*
     *
     * @param privateMessage
     * @param uid
     */
    @Override
    public void sendPrivateMessage(PrivateMessage<String> privateMessage, String uid) {
        checkFriend(Integer.valueOf(uid),privateMessage.getReceiveId());
        getUseInfo(privateMessage,uid);
        privateMessage.setType(1);

        PrivateChats privateChats = new PrivateChats();
        BeanUtil.updateProperties(privateMessage,privateChats);
        privateChats.setMessage(privateMessage.getMessage());

        boolean save = save(privateChats);
        if(save) {
            rabbitmqService.sendPrivateMessage(privateMessage,privateMessage.getReceiveId(),privateMessage.getSenderId());
        }
    }

    /**
     * 发送语音
     *
     * @param file
     * @param uid
     * @param receiveId
     */
    @Override
    public void sendPrivateSoundMessage(MultipartFile file, String uid, Integer receiveId) {
        checkFriend(Integer.valueOf(uid),receiveId);
        PrivateMessage<Object> privateMessage = new PrivateMessage<>();
        getUseInfo(privateMessage,uid);
        privateMessage.setType(3);
        privateMessage.setReceiveId(receiveId);

        String fileUrl = getFileUrl(file);
        privateMessage.setMessage(fileUrl);

        PrivateChats privateChats = new PrivateChats();
        BeanUtil.updateProperties(privateMessage,privateChats);
        privateChats.setMessage(fileUrl);

        boolean save = save(privateChats);
        if(save) {
            rabbitmqService.sendPrivateMessage(privateMessage,privateMessage.getReceiveId(),privateMessage.getSenderId());
        }
    }

    /**
     * 发送图片
     *
     * @param files
     * @param uid
     * @param receiveId
     */
    @Override
    public void sendPrivateImageMessage(MultipartFile[] files, String uid, Integer receiveId) {
        checkFriend(Integer.valueOf(uid),receiveId);
        PrivateMessage<List<String>> privateMessage = new PrivateMessage<>();
        getUseInfo(privateMessage,uid);
        privateMessage.setType(2);
        privateMessage.setReceiveId(receiveId);

        ResultVo<HashMap<String, List<String>>> hashMapResultVo = ossClint.uploadRoomFiles(files);
        if (!hashMapResultVo.getSucceed()) {
            throw new CommonException(ResultCode.CUSTOM_FAIL.setMessage("发送信息失败"));
        }
        HashMap<String, List<String>> data = hashMapResultVo.getData();
        List<String> url = data.get("url");
        privateMessage.setMessage(url);

        PrivateChats privateChats = new PrivateChats();
        BeanUtil.updateProperties(privateMessage,privateChats);
        privateChats.setMessage(JSON.toJSONString(url));

        boolean save = save(privateChats);
        if(save) {
            rabbitmqService.sendPrivateMessage(privateMessage,privateMessage.getReceiveId(),privateMessage.getSenderId());
        }
    }

    /**
     * send*
     *
     * @param fileMessageVo
     * @param uid
     */
    @Override
    public void sendPrivateFileMessage(FileMessageVo fileMessageVo, String uid) {
        checkFriend(Integer.valueOf(uid), fileMessageVo.getReceiveId());

        PrivateMessage<Object> privateMessage = new PrivateMessage<>();
        getUseInfo(privateMessage,uid);
        privateMessage.setReceiveId(fileMessageVo.getReceiveId());

        // 获取文件后缀名
        String fileName = fileMessageVo.getFileName();
        String hou = fileName.substring(fileName.lastIndexOf("."));
        
        PrivateChats privateChats = new PrivateChats();
        ResultVo<HashMap<String, String>> hashMapResultVo = ossClint.completeMultipartUpload(fileName, 
                fileMessageVo.getUploadId());
        if (!hashMapResultVo.getSucceed()) {
            System.err.println("出现异常");
            System.out.println(hashMapResultVo.getmessage());
            throw new CommonException(ResultCode.CUSTOM_FAIL.setMessage("发送文件失败"));
        }
        Map<String, String> data = hashMapResultVo.getData();
        String fileUrl = data.get("url");

        if (Filetype.MP3.getTypeName().equals(hou)) {
            privateMessage.setType(3);
            //获取文件地址
            privateMessage.setMessage(fileUrl);

            //数据库存档
            BeanUtil.updateProperties(privateMessage, privateChats);
            privateChats.setMessage(fileUrl);

        } else if (Filetype.IMAGE.getTypeName().equals(hou) || Filetype.PNG.getTypeName().equals(hou)) {
            privateMessage.setType(2);

            List<String> url = new LinkedList<>();
            url.add(fileUrl);
            privateMessage.setMessage(url);

            //数据库存档
            BeanUtil.updateProperties(privateMessage, privateChats);
            privateChats.setMessage(JSON.toJSONString(url));

        } else if (Filetype.MP4.getTypeName().equals(hou)) {
            privateMessage.setType(6);

            privateMessage.setMessage(fileUrl);
            BeanUtil.updateProperties(privateMessage, privateChats);
            privateChats.setMessage(fileUrl);

        } else {
            privateMessage.setType(5);
            //封装数据
            FileInfo fileInfo = new FileInfo();
            fileInfo.setName(fileMessageVo.getName());
            fileInfo.setSize(fileMessageVo.getSize());
            fileInfo.setUrl(fileUrl);
            privateMessage.setMessage(fileInfo);
            BeanUtil.updateProperties(privateMessage, privateChats);
            privateChats.setMessage(JSON.toJSONString(fileInfo));
        }
        boolean save = save(privateChats);
        if(save) {
            rabbitmqService.sendPrivateMessage(privateMessage,privateMessage.getReceiveId(),privateMessage.getSenderId());
        }
    }

    /**
     * 获取历史消息
     *
     * @param page
     * @param limit
     * @param fid
     * @param id
     * @param uid
     * @return
     */
    @Override
    public MyPage<PrivateChats> getHistoryPrivateMessage(Long page, Long limit, Integer fid, Integer id, Integer uid) {
        limit = limit < 1 ? 10 : limit;
        page = page < 1 ? 0 : (page - 1) * limit;
        checkFriend(uid,fid);
        if(page == 0) {
            id = Integer.MAX_VALUE;
        }
        List<PrivateChats> privateChats = privateChatsMapper.selectHistoryChat(page, limit, uid, fid, id);
        MyPage<PrivateChats> myPage = new MyPage<>();
        myPage.setContent(privateChats);
        myPage.setTotalElements(privateChatsMapper.selectCount(uid,fid));
        return myPage;
    }

    /**
     * 获取每个用户的最后一条信息*
     *
     * @param ids
     * @param uid *
     * @return
     */
    @Override
    public List<LastPrivateMessageDto> getLastMessage(List<Integer> ids, Integer uid) {
        List<LastPrivateMessageDto> lastPrivateMessage = privateChatsMapper.getLastPrivateMessage(ids, uid);
        return lastPrivateMessage;
    }


    public void checkFriend(Integer uid,Integer fid) {
        ResultVo<Map<String, Boolean>> mapResultVo = roomClient.checkIsFriend(uid, fid);
        if(!mapResultVo.getSucceed()) {
            throw new CommonException(ResultCode.CUSTOM_FAIL.setCode(90244).setMessage("发送信息失败"));
        }

        Map<String, Boolean> data = mapResultVo.getData();
        if(!data.get("result")) {
            throw  new CommonException(ResultCode.CUSTOM_FAIL.setCode(90244).setMessage("你们还不是好友"));
        }
    }

    public void getUseInfo(PrivateMessage message, String uid) {
        message.setSenderId(Integer.valueOf(uid));
        ResultVo<UserDto> userInfo = userClient.getUserInfo(uid);
        if (!userInfo.getSucceed()) {
            System.err.println("出现异常");
            throw new CommonException(ResultCode.CUSTOM_FAIL.setMessage("发送信息失败").setCode(90244));
        }
        UserDto users = userInfo.getData();
        message.setSenderName(users.getUserName());
        message.setSenderAvatar(users.getAvatar());
        message.setCreateTime(new Date());
    }

    public String getFileUrl(MultipartFile file) {
        ResultVo<HashMap<String, String>> hashMapResultVo = ossClint.uploadRoomFile(file);
        if (!hashMapResultVo.getSucceed()) {
            throw new CommonException(ResultCode.CUSTOM_FAIL.setMessage("文件发送失败"));
        }
        HashMap<String, String> data = hashMapResultVo.getData();
        String url = data.get("url");
        return url;
    }

}
